package com.edu.control.k8s;

import io.kubernetes.client.custom.IntOrString;
import io.kubernetes.client.custom.V1Patch;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.apis.AppsV1Api;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.apis.ExtensionsV1beta1Api;
import io.kubernetes.client.openapi.models.ExtensionsV1beta1Ingress;
import io.kubernetes.client.openapi.models.V1Deployment;
import io.kubernetes.client.openapi.models.V1Namespace;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
import io.kubernetes.client.openapi.models.V1PodList;
import io.kubernetes.client.openapi.models.V1ResourceQuota;
import io.kubernetes.client.openapi.models.V1ResourceQuotaList;
import io.kubernetes.client.openapi.models.V1Secret;
import io.kubernetes.client.openapi.models.V1Service;
import io.kubernetes.client.openapi.models.V1ServiceAccount;
import io.kubernetes.client.util.Config;
import okhttp3.Call;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Component
public class KubernetesApi {

    /***
     * 资源配置需要自动生成默认的命名空间、并绑定资源、同时给命名空间分配资源总大小
     * @return
     * @throws IOException
     * @throws ApiException
     */

    private static final Logger logger = LoggerFactory.getLogger(KubernetesApi.class);

    static {
        ApiClient apiClient = null;
        try {
            apiClient = Config.fromConfig(KubernetesApi.class.getClassLoader().getResourceAsStream("k8s/config"));
            Configuration.setDefaultApiClient(apiClient);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public V1PodList listNamespacedPod(String namespace, String pretty, Boolean allowWatchBookmarks, String _continue, String fieldSelector, String labelSelector, Integer limit, String resourceVersion, Integer timeoutSeconds, Boolean watch) throws ApiException {
        CoreV1Api apiInstance = new CoreV1Api();
        V1PodList v1PodList = apiInstance.listNamespacedPod(namespace,
                pretty,
                allowWatchBookmarks,
                _continue,
                fieldSelector,
                labelSelector,
                limit,
                resourceVersion,
                timeoutSeconds,
                watch);
        return v1PodList;
    }

    public Object createNamespace(V1Namespace v1Namespace) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1Namespace v1NamespaceResult = api.createNamespace(v1Namespace, null, null, null);
        return v1NamespaceResult;
    }

    public Object createNamespaceAndQuota(String namespace, V1ResourceQuota v1ResourceQuota) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1ResourceQuota v1ResourceQuotaResult = api.createNamespacedResourceQuota(namespace, v1ResourceQuota, null, null, null);
        return v1ResourceQuotaResult;
    }

    public Object getQuotaUsedByNamespaceAndQuotaName(String quotaName, String namespaceName) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1ResourceQuota v1ResourceQuota = api.readNamespacedResourceQuota(quotaName, namespaceName, null, null, null);
        return v1ResourceQuota;
    }

    public Object getQuotaUsedByNamespace(String namespaceName) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1ResourceQuotaList v1ResourceQuotaList = api.listNamespacedResourceQuota(namespaceName, null, null, null, null, null, null, null, null, null);
        return v1ResourceQuotaList;
    }

    public Object patchNamespaceResourceQuota(String quotaName, String namespaceName, V1Patch v1Patch) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1ResourceQuota v1ResourceQuotaResult = api.patchNamespacedResourceQuota(quotaName, namespaceName, v1Patch, null, null, null, null);
        return v1ResourceQuotaResult;
    }

    public Object deleteNamespaceByName(String namespaceName) throws ApiException, IOException {
        CoreV1Api api = new CoreV1Api();
        Call call = api.deleteNamespaceCall(namespaceName, null, null, null, null, null, null, null);
        Response response = call.execute();
        return response;
    }

    public Object createNamespacePrivateSecret(String namespaceName) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1Secret v1Secret = new V1Secret();
        v1Secret.setMetadata(new V1ObjectMeta().name("my-private-repo"));
        Map map = new HashMap(1);
        map.put(".dockerconfigjson", "{\"auths\": {\"clife-devops-docker.pkg.coding.net\": {\"username\": \"zhaolong.huang@clife.cn\",\"password\": \"=Ux_d{)Upg:2^MV@nO-/BGhOm!ashs%h\",\"email\": \"zhaolong.huang@clife.cn\",\"auth\": \"emhhb2xvbmcuaHVhbmdAY2xpZmUuY246PVV4X2R7KVVwZzoyXk1WQG5PLS9CR2hPbSFhc2hzJWg=\"}}}".getBytes());
        v1Secret.setData(map);
        v1Secret.setType("kubernetes.io/dockerconfigjson");
        V1Secret v1SecretResult = api.createNamespacedSecret(namespaceName, v1Secret, null, null, null);
        return v1SecretResult;
    }

    public Object createNamespacedServiceAccount(String namespaceName) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1Patch v1Patch = new V1Patch("[{" +
                "        \"op\" : \"add\"," +
                "        \"path\" : \"/imagePullSecrets\"," +
                "        \"value\" : [{\"name\":\"my-private-repo\"}]" +
                "    }]");
        V1ServiceAccount v1ServiceAccountResult = null;
        v1ServiceAccountResult = api.patchNamespacedServiceAccount("default", namespaceName, v1Patch, null, null, null, null);
        return v1ServiceAccountResult;
    }

    public Object createDeploymentOfNamespaces(String namespaceName, V1Deployment v1Deployment) throws ApiException {
        AppsV1Api appsV1Api = new AppsV1Api();
        V1Deployment v1DeploymentResult = appsV1Api.createNamespacedDeployment(namespaceName, v1Deployment, null, null, null);
        return v1DeploymentResult;
    }

    public Object createServiceOfNamespaces(String namespaceName, V1Service v1Service) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1Service v1ServiceResult = api.createNamespacedService(namespaceName, v1Service, null, null, null);
        return v1ServiceResult;
    }

    public Object createIngressOfNamespaces(String namespaceName, ExtensionsV1beta1Ingress extensionsV1beta1Ingress) throws ApiException {
        ExtensionsV1beta1Api extensionsV1beta1Api = new ExtensionsV1beta1Api();
        ExtensionsV1beta1Ingress extensionsV1beta1IngressResult = extensionsV1beta1Api.createNamespacedIngress(namespaceName, extensionsV1beta1Ingress, null, null, null);
        return extensionsV1beta1IngressResult;
    }

    public Object updateDeploymentOfNamespaces(String namespaceName, Map<String, String> map) throws ApiException {
        String tcpImage = map.remove("tcpImage");
        map.remove("isExistProductID");
        AppsV1Api appsV1Api = new AppsV1Api();
        StringBuilder value = new StringBuilder();
        for (Map.Entry entry : map.entrySet()) {
            value.append("{\"name\":" + "\"" + entry.getKey() + "\",");
            value.append("\"value\":" + "\"" + entry.getValue() + "\"}");
            value.append(",");
        }
        value.deleteCharAt(value.lastIndexOf(","));
        V1Patch v1Patch = new V1Patch("[{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env\"," +
                "        \"value\" : [" + value + "]}" +
                "]");
        V1Deployment v1Deployment = appsV1Api.patchNamespacedDeployment("clife-iot-tcp-server-dm-" + map.get("PRODUCT_ID"), namespaceName, v1Patch, null, null, null, null);
        return v1Deployment;
    }

    /*public Object updateDeploymentOfNamespaces(String namespaceName, Map<String ,String> map) throws ApiException {
        AppsV1Api appsV1Api = new AppsV1Api();
        V1Patch v1Patch = new V1Patch("[{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/image\"," +
                "        \"value\" : 1.0.4}" +
                "]");
        V1Deployment v1Deployment = appsV1Api.patchNamespacedDeployment("clife-iot-tcp-server-dm-" + map.get("PRODUCT_ID"), namespaceName, v1Patch, null, null, null, null);
        return v1Deployment;
    }*/

    public Object updateServiceOfNamespaces(String namespaceName, Map<String, String> map) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1Patch v1Patch = new V1Patch("[{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/0/port\"," +
                "        \"value\" : " + new IntOrString(map.get("TCP_PORT")) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/0/targetPort\"," +
                "        \"value\" : " + new IntOrString(map.get("TCP_PORT")) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/0/nodePort\"," +
                "        \"value\" : " + new IntOrString(map.get("TCP_PORT")) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/1/port\"," +
                "        \"value\" : " + new IntOrString(map.get("HTTP_PORT")) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/1/targetPort\"," +
                "        \"value\" : " + new IntOrString(map.get("HTTP_PORT")) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/1/nodePort\"," +
                "        \"value\" : " + new IntOrString(map.get("HTTP_PORT")) + "}" +
                "]");
        V1Service v1Service = api.patchNamespacedService("clife-iot-tcp-server-" + map.get("PRODUCT_ID"), namespaceName, v1Patch, null, null, null, null);
        return v1Service;
    }

    public Object updateIngressOfNamespaces(String namespaceName, Map<String, String> map) throws ApiException {
        ExtensionsV1beta1Api extensionsV1beta1Api = new ExtensionsV1beta1Api();
        V1Patch v1Patch = new V1Patch("[{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/rules/0/http/paths/0/backend/servicePort\"," +
                "        \"value\" : " + new IntOrString(map.get("TCP_PORT")) + "}]");
        ExtensionsV1beta1Ingress extensionsV1beta1Ingress = extensionsV1beta1Api.patchNamespacedIngress("clife-iot-tcp-server-ingress-" + map.get("PRODUCT_ID"), namespaceName, v1Patch, null, null, null, null);
        return extensionsV1beta1Ingress;
    }

    /*public Object updateDeploymentOfNamespaces(String namespaceName, TcpFunctionDefine tcpFunctionDefine) throws ApiException {
        ExtensionsV1beta1Api extensionsV1beta1Api = new ExtensionsV1beta1Api();
        V1Patch v1Patch = new V1Patch("[{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/0/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getKeepaliveTime() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/1/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getJavaOpts() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/2/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getDisconfOpts() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/3/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getNettyTcpPort() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/4/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getHttpServerPort() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/5/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getProductId() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/6/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getMsgMaxLen() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/7/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getDataSet() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/8/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getDataSize() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/9/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getDataType() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/10/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getDataCharset() + "\"}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/template/spec/containers/0/env/11/value\"," +
                "        \"value\" : \"" + tcpFunctionDefine.getMsgForward() + "\"}" +
                "]");
        ExtensionsV1beta1Deployment extensionsV1beta1Deployment = extensionsV1beta1Api.patchNamespacedDeployment("clife-iot-tcp-server-dm-" + tcpFunctionDefine.getProductId(), namespaceName, v1Patch, null, null, null, null);
        return extensionsV1beta1Deployment;
    }*/

    /*public Object updateServiceOfNamespaces(String namespaceName, TcpFunctionDefine tcpFunctionDefine) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1Patch v1Patch = new V1Patch("[{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/0/port\"," +
                "        \"value\" : " + new IntOrString(tcpFunctionDefine.getNettyTcpPort()) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/0/targetPort\"," +
                "        \"value\" : " + new IntOrString(tcpFunctionDefine.getNettyTcpPort()) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/0/nodePort\"," +
                "        \"value\" : " + new IntOrString(tcpFunctionDefine.getNettyTcpPort()) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/1/port\"," +
                "        \"value\" : " + new IntOrString(tcpFunctionDefine.getHttpServerPort()) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/1/targetPort\"," +
                "        \"value\" : " + new IntOrString(tcpFunctionDefine.getHttpServerPort()) + "}," +
                "{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/ports/1/nodePort\"," +
                "        \"value\" : " + new IntOrString(tcpFunctionDefine.getHttpServerPort()) + "}" +
                "]");
        V1Service v1Service = api.patchNamespacedService("clife-iot-tcp-server-" + tcpFunctionDefine.getProductId(), namespaceName, v1Patch, null, null, null, null);
        return v1Service;
    }

    public Object updateIngressOfNamespaces(String namespaceName, TcpFunctionDefine tcpFunctionDefine) throws ApiException {
        ExtensionsV1beta1Api extensionsV1beta1Api = new ExtensionsV1beta1Api();
        V1Patch v1Patch = new V1Patch("[{" +
                "        \"op\" : \"replace\"," +
                "        \"path\" : \"/spec/rules/0/http/paths/0/backend/servicePort\"," +
                "        \"value\" : " + new IntOrString(tcpFunctionDefine.getNettyTcpPort()) + "}]");
        ExtensionsV1beta1Ingress extensionsV1beta1Ingress = extensionsV1beta1Api.patchNamespacedIngress("clife-iot-tcp-server-ingress-" + tcpFunctionDefine.getProductId(), namespaceName, v1Patch, null, null, null, null);
        return extensionsV1beta1Ingress;
    }*/

    /**
     * 根据条件查询Pod
     *
     * @param namespace
     * @param labelSelector
     * @return V1PodList
     * @throws ApiException
     */
    public V1PodList listNamespacedPodByLabel(String namespace, String labelSelector) throws ApiException {
        CoreV1Api api = new CoreV1Api();
        V1PodList list = api.listNamespacedPod(namespace, "false", false, null, null, labelSelector, null, null, null, null);
        return list;
    }
}
